/*
 * PeerDiscovery.hpp
 *
 *  Created on: Jan 30, 2015
 *      Author: toti
 */

#ifndef PEERDISCOVERY_HPP_
#define PEERDISCOVERY_HPP_

#include <fstream>
#include <list>

#include <Misc/Config.hpp>
#include <Connectivity/UDPServer.hpp>
#include <Connectivity/UDPClient.hpp>
#include <Connectivity/EPoll.hpp>

class PeerDiscovery{

public:


	typedef struct PeerDiscoveryRequestData{
		in6_addr address;
		uint32_t port;
	}PeerDiscoveryRequestData_t;

	typedef struct PeerDiscoveryResponseData{
		in6_addr address;
		uint32_t port;
	}PeerDiscoveryResponseData_t;

private:

	Config *config;

	/*
	 * Log
	 */
	std::ofstream *logFileStream;

	/*
	 * Stuff for peer discovery
	 */
	std::list<PeerDiscoveryResponseData_t*> *peerDiscoveryResponseList;

	std::string multicastUDPPort;
	std::string unicastUDPPort;

	std::string multicastAddressString;
	std::string unicastAddressString;

	in6_addr multicastAddress;
	in6_addr unicastAddress;


	UDPServer *multicastUDPServer;
	UDPServer *unicastUDPServer;

	UDPClient *multicastUDPClient;

public:

	PeerDiscovery();

	void initPeerDiscovery(EPoll *epoll);

	void sendPeerDiscoveryRequest();
	int receivePeerDiscoveryRequest(PeerDiscoveryRequestData_t *peerDiscoveryRequestData);
	void replyPeerDiscoveryRequest(PeerDiscoveryRequestData_t *peerDiscoveryRequestData);
	PeerDiscoveryResponseData_t *receivePeerDiscoveryResponseData();

	void clearDiscoveredPeersList();
	void pushDiscoveryResponseList(PeerDiscoveryResponseData_t *peerDiscoveryResponseData);
	PeerDiscoveryResponseData_t *popDiscoveryResponseList();

	UDPServer *getMulticastUDPServer();
	UDPServer *getUnicastUDPServer();
};


#endif /* PEERDISCOVERY_HPP_ */
